iT邦幫忙

2021 iThome 鐵人賽

DAY 20
0
Modern Web

在JS的世界碰碰撞撞乒乒乓乓!30天一起玩Matter.js!系列 第 20

Day20. 麻痺手錶,小五郎叔叔的噩夢 - Sleeping

  • 分享至 

  • xImage
  •  

大家應該都看過名偵探柯南吧,那個智慧過於常人的小學生,東京死神,專長是踢足球跟在夏威夷學開飛機,興趣是用手錶把叔叔的脖子射得坑坑洞洞。

沒錯,我們的苦主毛利小五郎心理苦,但叔叔不說──我們今天要介紹的是 Sleeping 這個模組,被設定成 Sleeping 的物體,就像小五郎叔叔一樣,動也不動,直到被解除 Sleeping 的狀態為止。

今天的Demo
今天的Demo原始碼
https://ithelp.ithome.com.tw/upload/images/20211005/20142057Gtx0o5QwLO.png

開始看 Sleeping 這個模組前我們要先複習一下 body 上的兩個屬性:isSleeping 跟 sleepThreshold

//in default
sleepThreshold : 60
isSleeping : false

isSleeping 就是物體的初始狀態是否為 sleeping。

因為我們的 render option 有設定 showSleeping,如果是 sleeping 狀態的物體,會以稍暗的方式顯示。

sleepThreshold 則是在筆者撰寫文章的當下,又好好地看了一次,發現當初 Day8 的時候誤解他為速度的閥值,但其實不是(筆者寫這篇文章的時候已經改掉 Day8 的內容成正確的了)。

這個值要生效有一個前提條件是 engine 的 enableSleeping 要是 true。

var engine = Engine.create(options={
    enableSleeping : true
});

enableSleeping這個數值是用來做什麼的呢?

本來我對 sleeping 的作用也是有些困惑,搜尋後有看到 matter.js 的作者有回答一個提出的 issue

發問者好奇 sleeping 這個模組或是狀態當初設計的作用是什麼呢?作者回答,主要是用於讓一些完成碰撞檢測的物體進入 sleeping 狀態,可以帶來效能提升、減少 sleeping 物體的碰撞判斷,而當非 sleeping 物體與 sleeping 物體發生碰撞,則 sleeping 物體會被喚醒,進行運動。

整篇回答的重點在最後一句。

  • All you need to do is set engine.enableSleeping = true once when you create your engine. It will automatically handle the rest.

作者什麼都做好啦!只要你把 engine 的 enableSleeping 設成 true 允許 engine 透過 sleeping 模組來控制物體的 sleeping 狀態,他就會按邏輯來控制 sleeping 狀態,減小碰撞計算所花的效能,如堆疊在一起的靜止方盒,全部的方盒在沒有外力的情況下就都會是 sleeping 的狀態。

sleepThreshold 是建立在上面這個設定被設成 enable 的前提之下,規範當物體的在幾次udpate皆速度趨近於零則改變他的 sleeping 狀態,數字越小則越快進入 sleeping 的狀態,預設為 60。

雖然作者說交給 engine 自己處理就好,我們還是來看一下 sleeping 的方法們,總共有三個方法

  • Matter.Sleeping.afterCollisions(pairs, timeScale)
  • Matter.Sleeping.update(bodies, timeScale)
  • Matter.Sleeping.set(body, isSleeping)

第一個把 pair 當作傳入參數,很明顯主要是讓本來函式庫邏輯使用,這個我們就不深究。

第二個 update 方法可以看看原始碼,這邊可以看到上面提到的 sleepThreshold 被拿來檢測的痕跡,呼叫時機也是交由函式庫處理就好。

最後一個 set 是可以拿來試試的 function,使用上也很單純,就是傳入物體與要設置的狀態。

Sleeping 的狀態一旦物體本身仍有外力作用殘存,就會被喚醒, 如範例中的方塊撞到球,即使按下 trigger 球改變 sleeping 狀態的按鈕,球仍不會馬上進入 sleeping,必須等動能處理完。

如果 engine 的 enableSleeping 設成 false,則 engine 不會調動 Sleeping 模組來更新物體的 Sleeping 狀態,讀者可以試試這個改動(按一下 "Remove enableSleeping from engine" 按鈕再開始 runner ),方形落下後不會變成 Sleeping,碰到球體球體也不為所動。

其實這篇文章的重點就是在上面那個作者回答的最後一句,如果想增加碰撞判斷的效能,把 engine 中的 enableSleeping 設成 true就好啦!


上一篇
Day19. 手牽手,我的朋友,物體永遠在你左右 - Constraint
下一篇
Day21. 伸縮自如的,向量圖像砲 - SVG
系列文
在JS的世界碰碰撞撞乒乒乓乓!30天一起玩Matter.js!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言